﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Calc_2
{
    public partial class Calc : Form
    {
        string first, second, oper;
        double result, x, y;           
        bool flagAction = false, flagEqualPressed = false, flag3=false, flagError=false;
        string memory;

        public Calc()
        {
            InitializeComponent();
        }

        private void CheckText(Button c) //проверка, добавлять в конец число или же на новое поле
        {
            lableWarning.Text = ""; //этот лейбл для оповещения

            if (flagAction == true)  //проверяем, было ли выбрано какое-то действие, если да - очищаем поле
                TBnumbers.Text = " ";

            if (flagEqualPressed != true) //если уже было нажато равно, то это число не добавляется в конец числа
                TBnumbers.Text = TBnumbers.Text + c.Text;
            else
            {
                TBnumbers.Text = c.Text;
                flagEqualPressed = false;
            }
            flagAction = false;
            int s = TBnumbers.Text.Length;
            TBnumbers.Select(s, 0);
        }
        private void Replacement(string s) //т.к. нельзя конвертировать число с точкой (должно быть с запятой)
        {
            try
            {
                if (s == "second")
                    second = second.Replace(".", ","); //заменяем точку на запятую
                if (s == "first")
                    first = first.Replace(".", ","); //заменяем точку на запятую
            }
            catch (Exception a)
            {}
       
        }
        private void Result()
        {
            second = TBnumbers.Text;
            TBnumbers.Text = "";
            
            Replacement("second");
            Replacement("first");
           
            x = Convert.ToDouble(first);            
           
           
            if (second == "")
                y = 0;
            else
                y = Convert.ToDouble(second);

            if (oper == "+")
                result = x + y;

            if (oper == "-")
                result = x - y;

            if (oper == "/")
            {
                if (second != "0")
                    result = x / y;
                else
                    TBnumbers.Text = "0";
            }

            if (oper == "*")
                result = x * y;

            if (oper == "^")
                result = Math.Pow(x, y);
         

           
            TBnumbers.Text = Convert.ToString(result);
            flagAction = true;
            flagEqualPressed = true;
            int s = TBnumbers.Text.Length;
            TBnumbers.Select(s, 0);
        }
        private void Calc_Load(object sender, EventArgs e)
        {          
            TBnumbers.Text = "0";
            TBnumbers.Select();       
            
        }

        private void but1_Click(object sender, EventArgs e) //используется для всех кнопок с цифрами
        {               
            if (!flag3) //если вводим цифры сразу после запуска, то очищаем поле от нуля, который стоит по умолчанию
                TBnumbers.Text = "";
            flag3 = true;
            Button numbers = (Button)sender;
            CheckText(numbers);
            TBnumbers.Focus();
        }

        //очистка поля
        private void clearB_Click(object sender, EventArgs e)
        {
            TBnumbers.Text="0";
            flag3 = false;
            TBnumbers.Focus();
        }
        //ф-я удаления последнего числа
        private void DelLast()
        {
            int last= TBnumbers.Text.Count();

            if(TBnumbers.Text.Count()!=0)
                TBnumbers.Text = TBnumbers.Text.Remove(last - 1);

            int s=TBnumbers.Text.Length;
            TBnumbers.Select(s, 0);
        }
        //удаление одного символа с конца
        private void delB_Click(object sender, EventArgs e)
        {
            DelLast();
        }

        //запятая
        private void commaB_Click(object sender, EventArgs e)
        {
            if (TBnumbers.Text.Contains(","))
                return;
            
            TBnumbers.Text = TBnumbers.Text + commaB.Text;
            TBnumbers.Focus();
        }

        private void OperFun() //для требующих второго числа
        {
            first = TBnumbers.Text; //записываем первое число для вычисления результата
            Replacement(first);
            flagAction = true;
            TBnumbers.Focus();
        }

    
        private void plusB_Click(object sender, EventArgs e) //будет выполняться для +,-,\,*
        {
            Button operations = (Button)sender;
            oper = operations.Text;
            flagAction = true; //раньше не было и работало нормально
            OperFun();
        }

        private void OperFun2() //для НЕ требующих второго числа
        {
            first = TBnumbers.Text;
            Replacement(first);
            flagAction = true;
            if (first == "")
                x = 0;
            else
             x = Convert.ToDouble(first);
        }
        //возведение экспоненты в степень
        private void expB_Click(object sender, EventArgs e)
        {
            OperFun2();    
            result = Math.Exp(x);
            TBnumbers.Text = Convert.ToString(result);
            flagEqualPressed = true;
            TBnumbers.Focus();
        }
        //извлечение корня
        private void sqrtB_Click(object sender, EventArgs e)
        {
            OperFun2();
            if (x >= 0)
            {
                result = Math.Sqrt(x);
                TBnumbers.Text = Convert.ToString(result);
            }
            else
            {
                lableWarning.Text = "Нельзя извлечь корень из"+Environment.NewLine+ " отрицательного числа";
                TBnumbers.Text = "";
                flagError = true;
            }
            
            flagEqualPressed = true;
            TBnumbers.Focus();
        }
        //константа ПИ
        private void piB_Click(object sender, EventArgs e)
        {
            flagAction = true;
            TBnumbers.Text = Convert.ToString(Math.PI);
            result = Math.PI;
        }
        //возведение числа в степень
        private void powB_Click(object sender, EventArgs e)
        {
            first = TBnumbers.Text;
            Replacement(first);
            flagAction = true;
            oper = "^";
            TBnumbers.Focus();
        }
        //деление единицы на число
        private void obratB_Click(object sender, EventArgs e)
        {
            OperFun2();
            result = 1 / x;
            TBnumbers.Text = Convert.ToString(result);
            flagEqualPressed = true;
            TBnumbers.Focus();
        }
        //обратный знак
        private void sighnB_Click(object sender, EventArgs e)
        {
            OperFun2();
            result = x * (-1);
            TBnumbers.Text = Convert.ToString(result);
            flagEqualPressed = true;
            TBnumbers.Focus();
        }
        //вычисление факториала
        private void factB_Click(object sender, EventArgs e)
        {
            first = TBnumbers.Text;
            Replacement(first);
            flagAction = true; int a;
            try
            {
               a = Convert.ToInt32(first);
            }
            catch(Exception b)
            {
                a = 0;
                flagError = true;
                lableWarning.Text = "Значение должно быть" + Environment.NewLine + "   целочисленным";
            }
            if (a==0) result = 1;

            if (a > 0)
            {
                int num = a;
                result = num;
                for (int i = 0; i < a - 1; i++)
                {
                    num = num - 1;
                    result = result * num;
                }
            }
            if(a<0)
                lableWarning.Text = "Значение должно быть"+ Environment.NewLine + "   положительным";

            if ((flagError)||(a<0))
                TBnumbers.Text = "";
            else
                TBnumbers.Text = Convert.ToString(result);

            flagEqualPressed = true;
            TBnumbers.Focus();
           
        }
        //возведение в квадрат
        private void pow2B_Click(object sender, EventArgs e)
        {
            OperFun2();
            result = x * x;
            TBnumbers.Text = Convert.ToString(result);
            flagEqualPressed = true;
            TBnumbers.Focus();
        }
        //выведение результата
        private void equalB_Click(object sender, EventArgs e)
        { 
            Result();
            TBnumbers.Focus();
        }
        //запись в память
        private void memB_Click(object sender, EventArgs e)
        {
            memory = TBnumbers.Text;
            flagEqualPressed = true;
            TBnumbers.Focus();
        }
        //извлечение из памяти
        private void frommemB_Click(object sender, EventArgs e)
        {
            TBnumbers.Text = memory;
            flagEqualPressed = true;
            TBnumbers.Focus();
        }


       private void TBnumbers_KeyPress(object sender, KeyPressEventArgs e)
        {
            lableWarning.Text = "";
            if (Char.IsNumber(e.KeyChar) || (!string.IsNullOrEmpty(TBnumbers.Text) && (e.KeyChar == '.' || e.KeyChar == ',')))
            {
                if (flagAction == true)  //проверяем, было ли выбрано какое-то действие
                    TBnumbers.Text = " ";
                else
                    flagEqualPressed = false;

                flagAction = false;

                return;
            }
            else
            {
                if ((e.KeyChar == '-') || (e.KeyChar == '/') || (e.KeyChar == '*') || (e.KeyChar == '+'))
                {
                    oper = e.KeyChar.ToString();
                    OperFun();
                }

                if (e.KeyChar.ToString() == "\r") //проверка на нажатие enter
                    Result();
                if (e.KeyChar.ToString() == "\b") //проверка на нажатие <-
                    DelLast();                
             }
            e.Handled = true;
            TBnumbers.Focus();
        }

      
     
    }

    
}
